package com.nuoniu.sibanyun.service.erp.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.erp.ErpAccount;
import com.nuoniu.sibanyun.entity.erp.ErpCurrency;
import com.nuoniu.sibanyun.entity.erp.ErpCurrencyAccount;
import com.nuoniu.sibanyun.mapper.erp.ErpCurrencyMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpAccountingService;
import com.nuoniu.sibanyun.service.erp.IErpCurrencyAccountService;
import com.nuoniu.sibanyun.service.erp.IErpCurrencyService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.List;

/**
 * <p>
 *  货币服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-10-12
 */
@Service
public class ErpCurrencyServiceImpl extends ServiceImpl<ErpCurrencyMapper, ErpCurrency> implements IErpCurrencyService {

    @Autowired
    private IErpAccountService erpAccountService;
    @Autowired
    private IErpCurrencyAccountService currencyAccountService;
    @Autowired
    private IErpAccountingService accountingService;

    @Override
    public Page<ErpCurrency> pageList(Page pages, ErpCurrency currency) {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<ErpCurrency> queryWrapper = new QueryWrapper<>(currency);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        queryWrapper.eq("account_id", erpAccountService.getCurrentAccountId());
        queryWrapper.orderByDesc("is_base_currency");
        Page page = page(pages, queryWrapper);
        return page;
    }

    @Override
    @Transactional
    public void saveCurrency(ErpCurrency currency) {
        Integer accountId = erpAccountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();

        ErpCurrency currencyByCode = baseMapper.getByCode(userInfo.getCompanyId(), currency.getCode());
        if(currencyByCode != null && (currency.getId() == null || !currencyByCode.getId().equals(currency.getId()))) {
            throw new NuoNiuException("编码已存在");
        }

        ErpCurrency currencyByName = baseMapper.getByName(userInfo.getCompanyId(), currency.getName());
        if(currencyByName != null && (currency.getId() == null || !currencyByName.getId().equals(currency.getId()))) {
            throw new NuoNiuException("名称已存在");
        }

        if(currency.getIsBaseCurrency()) { //切换本位币
            currency.setCalDirection(null);
            currency.setExchangeRate(null);
            currency.setExChangeRateType(null);
            ErpCurrency erpCurrency = baseMapper.getByIsBase(userInfo.getCompanyId());
            if(erpCurrency != null && (currency.getId() == null || !erpCurrency.getId().equals(currency.getId()))) {
                erpCurrency.setIsBaseCurrency(false);
                updateById(erpCurrency);
            }
        }

        if(currency.getId() != null) {
            Integer count = accountingService.getByCurrency(currency.getId());
            if(count > 0) {
                throw new NuoNiuException("币种已使用，不能修改");
            }

            ErpCurrency currencyByType = getById(currency.getId());
            if(!currency.getIsBaseCurrency() && currencyByType.getIsBaseCurrency()) {
                throw new NuoNiuException("必须有一个本位币币种");
            }

            if(currency.getExChangeRateType() != null && !currency.getExChangeRateType().equals(currencyByType.getExChangeRateType())) {
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("currency_id", currency.getId());
                wrapper.eq("type", currencyByType.getExChangeRateType());
                currencyAccountService.remove(wrapper);
            }
            currency.setUpdatedDate(LocalDate.now());
            currency.setUpdatedUserId(userInfo.getUserId());
        }else {
            currency.setCompanyId(userInfo.getCompanyId());
            currency.setAccountId(accountId);
            currency.setCreatedUserId(userInfo.getUserId());
        }

        Boolean result = this.saveOrUpdate(currency);
        if(result && !currency.getIsBaseCurrency()) { //保存明细
            currency.getOrderList().forEach(p -> {
                p.setCurrencyId(currency.getId().intValue());
                p.setType(currency.getExChangeRateType());
            });
            currencyAccountService.saveBatch(currency.getOrderList());
        }
    }

    @Override
    public List<ErpCurrency> getAll(Boolean isBaseCurrency) {
        Integer accountId = erpAccountService.getCurrentAccountId();
        ErpCurrency currency = new ErpCurrency();
        QueryWrapper<ErpCurrency> queryWrapper = new QueryWrapper<>(currency);
        queryWrapper.eq("company_id", UserThreadLocal.get().getCompanyId());
        queryWrapper.eq("account_id", accountId);
        if(isBaseCurrency != null && !isBaseCurrency) {
            queryWrapper.eq("is_base_currency", 0);
        }
        return list(queryWrapper);
    }

    @Override
    public List<ErpCurrencyAccount> getDetailList(Integer currencyId, Integer year, Integer month) {
        QueryWrapper<ErpCurrencyAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("currency_id", currencyId);
        if(year != null) {
            queryWrapper.eq("year", year);
        }
        if(month != null) {
            queryWrapper.eq("month", month);
        }

        return currencyAccountService.list(queryWrapper);
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        for(Long id : ids) {
            ErpCurrency currency = getById(id);
            if(currency != null && currency.getIsBaseCurrency()) {
                throw new NuoNiuException("本位币不能删除");
            }

            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("currency_id", id);
            currencyAccountService.remove(wrapper);
        }
        this.removeByIds(ids);
    }

    @Override
    @Async
    public void initData(UserInfo userInfo, Integer id) {
        ErpCurrency currency = new ErpCurrency();
        ErpAccount account = erpAccountService.getById(id);
        currency.setCompanyId(userInfo.getCompanyId());
        currency.setAccountId(id);
        currency.setAccountYear(account.getAccountYear());
        currency.setIsBaseCurrency(true);
        currency.setCurrencySign("RMB");
        currency.setCode("01");
        currency.setName("人民币");
        save(currency);
    }

    @Override
    public ErpCurrency getCurrencyDetail(Long id) {
        ErpCurrency currency = getById(id);
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH) + 1;

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("currency_id", id);
        wrapper.eq("month", month);
        wrapper.eq("year", calendar.get(Calendar.YEAR));
        List<ErpCurrencyAccount> currencyAccounts = currencyAccountService.list(wrapper);

        if(currencyAccounts != null && currencyAccounts.size() > 0) {
            currency.setOrderList(currencyAccounts);
        }

        return currency;
    }
}
